package whf.framework.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;

import org.hibernate.Hibernate;

import whf.framework.entity.Entity;

/**
 * @author wanghaifeng
 * @create Mar 13, 2007 10:16:13 PM
 * 
 */
public class BeanInitialization {
	/**
	 * @property ThreadLocal<String[]>:initializeProperties
	 */
	private static ThreadLocal<String[]> initializeProperties = new ThreadLocal<String[]>();
	
	private static ThreadLocal<Integer> initializeDeepth = new ThreadLocal<Integer>();
	
	private BeanInitialization(){
		//
	}
	
	public static void setInitializeProperties(String[] props){
		initializeProperties.set(props);
	}
	
	public static void setInitializeProperties(String[] props, int deepth){
		initializeProperties.set(props);
		initializeDeepth.set(deepth);
	}
	
	/**
	 * 同下
	 * @modify wanghaifeng Oct 16, 2006 2:26:25 PM
	 * @param bean
	 */
	public static void initializeBean(Object bean){
		int deepth = 5;
		if(initializeDeepth.get() != null){
			deepth = initializeDeepth.get();
		}
		initBean(bean, 0, deepth);
		initializeProperties.set(null);
		initializeDeepth.set(null);
	}
	
	public static void initializeBean(Object bean, int deepth, int maxDeepth){
		initBean(bean, deepth, maxDeepth);
		initializeProperties.set(null);
	}
	
	/**
	 * 初始化bean,用来处理lazy load
	 * @modify wanghaifeng Oct 16, 2006 2:25:50 PM
	 * @param bean
	 * @param deepth
	 * @param maxDeepth
	 */
	private static void initBean(Object bean, int deepth, int maxDeepth){
		if(deepth > maxDeepth) return;
		if(bean == null) return;
		if(!(bean instanceof Entity )) return;
		deepth ++;
		Class cls = bean.getClass();
		PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(cls);
		String[] initProps = initializeProperties.get();
		for(PropertyDescriptor descriptor: descriptors){
			String propertyName = descriptor.getName();
			if(initProps != null && initProps.length > 0){
				boolean found = false;
				for(String pn: initProps){
					if(propertyName.equals(pn)){
						found = true;
						break;
					} else {
						continue;
					}
				}
				if(!found){
					continue;
				}
			}
			Method readMethod = descriptor.getReadMethod();
			Object propertyValue = null;
			if(readMethod != null){
				try{
					propertyValue = readMethod.invoke(bean, BeanUtils.METHOD_EMPTY_PARAMS);
				}catch(Exception ignore){
					//
				}
			}
			if(propertyValue != null && propertyValue != bean ){
				if(propertyValue instanceof Entity){
					initBean(propertyValue,deepth, maxDeepth);
				} else if(propertyValue instanceof Collection){
					for(Iterator it = ((Collection)propertyValue).iterator();it.hasNext();){
						initBean(it.next(), deepth, maxDeepth);
					}
				}
			}
		}
	}
	//
	public static void initialize(Object obj){
		Hibernate.initialize(obj);
	}
	
	public static boolean isInitialized(Object obj){
		return Hibernate.isInitialized(obj);
	}
	
	public static boolean isPropertyInitialized(Object obj, String prop){
		return Hibernate.isPropertyInitialized(obj, prop);
	}
}
